// ========================================================
//
//	  File: Vector.chpl
//	Author: Patrick Copeland
//	  Date: 27 January 2012
//	  Time: 23:00
//	  Desc: Java vector in Chapel
//
//			Without null, there is not a good way to
//			keep track of the size. Fix not know at this
//			point.
//
// ========================================================


class Vector {
	
	// instance variables
	type itemType;
	var size:int;
	var capacity:int;
	var D:domain(1);
	var array:[D] itemType;

	// constructor
	proc Vector(type itemType) {
		this(itemType, 10);
	}
	
	// constructor
	proc Vector(type itemType, initialCapacity:int) {
		//this.itemType = itemType;
		this.size = 0;
		this.capacity = initialCapacity;
		this.D = [0..initialCapacity-1];
		
		//forall i in D {
		//	this.array[i] = 0;
		//}
	}
	
	// Inserts the specified element at the specified position in this Vector.
	proc add(i:int, element:itemType) {
		while (i > this.capacity-1) {
			this.capacity = this.capacity * 2;
			this.D = [0..this.capacity-1];
		}
		
		this.capacity = this.capacity + 1;	// add one for shift
		this.D = [0..this.capacity-1];
		
		this.array[i+1..this.capacity-1] = this.array[i..this.capacity-2];
		this.array[i] = element;
		this.size = this.size + 1;
	}
	
	// Adds the specified component to the end of this vector, 
	// increasing its size by one.
	proc add(element:itemType) {
		var oldCapacity = this.capacity;
		this.capacity = this.capacity *2;
		this.D = [0..this.capacity-1];
		
		this.array[oldCapacity] = element;
		this.size = this.size + 1;
		
	}
	
	
	proc contains(element:itemType) : bool {
		var contained = false;
		
		forall i in D {
			if array[i] == element {
				contained = true;
			}
		}
		
		return contained;
	}
	
	proc elementAt(i:int) : itemType {
		return this.array[i];
	}
	
	proc getCapacity() : int {
		return this.capacity;
	}
	
	proc getSize() : int {
		return this.size;
	}
	
	proc isEmpty() : bool {
		return this.size == 0;
	}
	
	// Replaces the element at the specified position in this Vector
	// with the specified element and returns the element previously
	// at the specified location
	proc set(i:int, element:itemType) : itemType{
		var oldElement = this.array[i];
		this.array[i] = element;
		return oldElement;
	}
	
	proc toArray() {
		return this.array;
	}
	
	proc toString() {
		return this.array:string;
	}
	

}

// end Vector.chpl